package com.yuanqi.service.impl;

import com.yuanqi.entity.Inventory;
import com.yuanqi.mapper.InventoryMapper;
import com.yuanqi.service.InventoryStatsService;
import com.yuanqi.vo.InventoryStatsVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 库存统计服务实现类
 */
@Service
public class InventoryStatsServiceImpl implements InventoryStatsService {

    @Autowired
    private InventoryMapper inventoryMapper;

    @Override
    public List<InventoryStatsVO> getInventoryStatsList(Map<String, Object> params) {
        // 构建查询条件
        Map<String, Object> queryParams = buildQueryParams(params);
        
        // 分页参数
        Integer page = (Integer) params.getOrDefault("page", 1);
        Integer size = (Integer) params.getOrDefault("size", 20);
        int offset = (page - 1) * size;
        queryParams.put("offset", offset);
        queryParams.put("limit", size);
        
        // 排序参数
        String sortField = (String) params.get("sortField");
        String sortOrder = (String) params.get("sortOrder");
        if (sortField != null && !sortField.isEmpty()) {
            queryParams.put("sortField", sortField);
            queryParams.put("sortOrder", sortOrder != null ? sortOrder : "asc");
        }
        
        // 执行查询
        List<Map<String, Object>> results = inventoryMapper.selectInventoryStatsList(queryParams);
        
        // 转换为VO
        List<InventoryStatsVO> voList = new ArrayList<>();
        for (Map<String, Object> result : results) {
            InventoryStatsVO vo = convertToVO(result);
            voList.add(vo);
        }
        
        return voList;
    }

    @Override
    public long getInventoryStatsCount(Map<String, Object> params) {
        Map<String, Object> queryParams = buildQueryParams(params);
        return inventoryMapper.selectInventoryStatsCount(queryParams);
    }

    @Override
    public Map<String, Object> getInventoryStats(Map<String, Object> params) {
        Map<String, Object> queryParams = buildQueryParams(params);
        
        // 获取统计数据
        Map<String, Object> stats = inventoryMapper.selectInventoryStats(queryParams);
        
        // 计算库存状态统计
        long totalCount = getInventoryStatsCount(params);
        long sufficientCount = inventoryMapper.selectInventoryStatsCountByStatus(queryParams, "sufficient");
        long insufficientCount = inventoryMapper.selectInventoryStatsCountByStatus(queryParams, "insufficient");
        long zeroCount = inventoryMapper.selectInventoryStatsCountByStatus(queryParams, "zero");
        
        Map<String, Object> result = new HashMap<>();
        result.put("totalSkuCount", totalCount);
        result.put("sufficientCount", sufficientCount);
        result.put("insufficientCount", insufficientCount);
        result.put("zeroCount", zeroCount);
        
        // 添加其他统计数据
        if (stats != null) {
            result.putAll(stats);
        }
        
        return result;
    }

    @Override
    public Map<String, Object> getInventoryOverview(Map<String, Object> params) {
        Map<String, Object> queryParams = buildQueryParams(params);
        
        // 获取概览数据
        Map<String, Object> overview = inventoryMapper.selectInventoryOverview(queryParams);
        
        if (overview == null) {
            overview = new HashMap<>();
        }
        
        // 确保有默认值
        overview.putIfAbsent("totalSkuCount", 0);
        overview.putIfAbsent("totalValue", BigDecimal.ZERO);
        overview.putIfAbsent("averageValue", BigDecimal.ZERO);
        overview.putIfAbsent("maxValue", BigDecimal.ZERO);
        overview.putIfAbsent("minValue", BigDecimal.ZERO);
        
        return overview;
    }

    @Override
    public void exportInventoryStats(Map<String, Object> params, HttpServletResponse response) {
        try {
            // 获取所有数据（不分页）
            Map<String, Object> exportParams = new HashMap<>(params);
            exportParams.put("page", 1);
            exportParams.put("size", Integer.MAX_VALUE);
            
            List<InventoryStatsVO> dataList = getInventoryStatsList(exportParams);
            
            // 生成CSV格式的导出数据
            response.setContentType("text/csv;charset=utf-8");
            response.setCharacterEncoding("utf-8");
            
            PrintWriter writer = response.getWriter();
            
            // 写入BOM以支持中文
            writer.write('\ufeff');
            
            // 写入表头
            writer.println("商品编码,商品名称,商品分类,仓库,库位,批次号,有效期,在库数量,可用数量,占用数量,单位成本,库存总价值,库存状态,更新时间");
            
            // 写入数据
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for (InventoryStatsVO vo : dataList) {
                writer.println(String.format("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s",
                    vo.getSkuCode() != null ? vo.getSkuCode() : "",
                    vo.getSkuName() != null ? vo.getSkuName() : "",
                    vo.getCategoryName() != null ? vo.getCategoryName() : "",
                    vo.getWarehouseName() != null ? vo.getWarehouseName() : "",
                    vo.getLocationName() != null ? vo.getLocationName() : "",
                    vo.getBatchNo() != null ? vo.getBatchNo() : "",
                    vo.getExpiryDate() != null ? new SimpleDateFormat("yyyy-MM-dd").format(vo.getExpiryDate()) : "",
                    vo.getOnHandQty() != null ? vo.getOnHandQty().toString() : "0",
                    vo.getAvailableQty() != null ? vo.getAvailableQty().toString() : "0",
                    vo.getOccupiedQty() != null ? vo.getOccupiedQty().toString() : "0",
                    vo.getUnitCost() != null ? vo.getUnitCost().toString() : "0",
                    vo.getTotalValue() != null ? vo.getTotalValue().toString() : "0",
                    getStockStatusText(vo.getStockStatus()),
                    vo.getUpdatedAt() != null ? dateFormat.format(vo.getUpdatedAt()) : ""
                ));
            }
            
            writer.flush();
            writer.close();
            
        } catch (IOException e) {
            throw new RuntimeException("导出失败", e);
        }
    }

    @Override
    public List<Map<String, Object>> getWarehouseValueData(Map<String, Object> params) {
        Map<String, Object> queryParams = buildQueryParams(params);
        return inventoryMapper.selectWarehouseValueData(queryParams);
    }

    @Override
    public List<Map<String, Object>> getCategoryQuantityData(Map<String, Object> params) {
        Map<String, Object> queryParams = buildQueryParams(params);
        return inventoryMapper.selectCategoryQuantityData(queryParams);
    }

    /**
     * 构建查询参数
     */
    private Map<String, Object> buildQueryParams(Map<String, Object> params) {
        Map<String, Object> queryParams = new HashMap<>();
        
        // 复制参数
        queryParams.putAll(params);
        
        // 处理商品名称模糊查询
        String skuName = (String) params.get("skuName");
        if (skuName != null && !skuName.trim().isEmpty()) {
            queryParams.put("skuName", "%" + skuName.trim() + "%");
        }
        
        return queryParams;
    }

    /**
     * 转换为VO对象
     */
    private InventoryStatsVO convertToVO(Map<String, Object> result) {
        InventoryStatsVO vo = new InventoryStatsVO();
        
        vo.setId(getLongValue(result, "id"));
        vo.setSkuCode(getStringValue(result, "sku_code"));
        vo.setSkuName(getStringValue(result, "sku_name"));
        vo.setCategoryId(getLongValue(result, "category_id"));
        vo.setCategoryName(getStringValue(result, "category_name"));
        vo.setWarehouseId(getLongValue(result, "warehouse_id"));
        vo.setWarehouseName(getStringValue(result, "warehouse_name"));
        vo.setLocationId(getLongValue(result, "location_id"));
        vo.setLocationName(getStringValue(result, "location_name"));
        vo.setBatchNo(getStringValue(result, "batch_no"));
        vo.setExpiryDate(getDateValue(result, "expiry_date"));
        vo.setOnHandQty(getBigDecimalValue(result, "on_hand_qty"));
        vo.setAvailableQty(getBigDecimalValue(result, "available_qty"));
        vo.setOccupiedQty(getBigDecimalValue(result, "occupied_qty"));
        vo.setUnitCost(getBigDecimalValue(result, "unit_cost"));
        vo.setTotalValue(getBigDecimalValue(result, "total_value"));
        vo.setStockStatus(getStringValue(result, "stock_status"));
        vo.setUpdatedAt(getDateValue(result, "updated_at"));
        
        return vo;
    }

    /**
     * 获取库存状态文本
     */
    private String getStockStatusText(String status) {
        if (status == null) return "未知";
        
        switch (status) {
            case "sufficient":
                return "库存充足";
            case "insufficient":
                return "库存不足";
            case "zero":
                return "零库存";
            default:
                return "未知";
        }
    }

    // 辅助方法
    private Long getLongValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) return null;
        if (value instanceof Long) return (Long) value;
        if (value instanceof Number) return ((Number) value).longValue();
        return null;
    }

    private String getStringValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        return value != null ? value.toString() : null;
    }

    private BigDecimal getBigDecimalValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) return null;
        if (value instanceof BigDecimal) return (BigDecimal) value;
        if (value instanceof Number) return new BigDecimal(value.toString());
        return null;
    }

    private Date getDateValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) return null;
        if (value instanceof Date) return (Date) value;
        if (value instanceof java.sql.Timestamp) return new Date(((java.sql.Timestamp) value).getTime());
        return null;
    }
}